﻿using System;
using System.Reflection;
using System.Threading;
using ZilLion.Service.Core.ConfigManager.Attribute;
using ZilLion.Service.Core.ConfigManager.Interface;

namespace ZilLion.Service.Core.ConfigManager.Cache
{
    /// <summary>
    ///     存config容器,并指定刷新策略等值
    /// </summary>
    public class ConfigInstanceContainer<T> : IConfigInstanceContainer where T : class, new()
    {
        public int RefreshInterval { get; set; }
        public IConfigProvider ConfigProvider { get; set; }
        public object ConfigInstance { get; set; }
        public ConfigInstanceContainer()
        {
            var configurationArgumentAttribute = typeof(T).GetCustomAttribute<ConfigurationArgumentAttribute>();

            if (configurationArgumentAttribute==null) throw new Exception($"{typeof(T).FullName } 不是一个可配置模型");

            ConfigProvider = configurationArgumentAttribute.ProviderInstance;
            ConfigInstance = configurationArgumentAttribute.ProviderInstance.LoadConfig() as T;

            if (ConfigInstance == null)//当取值出问题，强制初始化配置
            {
                var instance=new T();
                configurationArgumentAttribute.ProviderInstance.CurrentConfigInstance = instance;
                configurationArgumentAttribute.ProviderInstance.SaveConfig(instance);
            }

            RefreshInterval = configurationArgumentAttribute.RefreshInterval;

            if (RefreshInterval > 0)
            {

                var refreshThread = new Thread(() =>
                {
                    while (true)
                    {
                        Thread.Sleep(RefreshInterval);
                        ConfigInstance = configurationArgumentAttribute.ProviderInstance.LoadConfig() as T;

                    }
                    // ReSharper disable once FunctionNeverReturns
                }) { IsBackground = true };
                refreshThread.SetApartmentState(ApartmentState.MTA);
                refreshThread.Start();


            }
        }

        /// <summary>
        /// 保存配置
        /// </summary>
        public void SaveConfig()
        {
            ConfigProvider.SaveConfig(ConfigInstance);
        }


    }
}